package com.grao.waterschool.human.manager.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.lang.Assert;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.grao.waterschool.human.entiry.dto.LoginInfo;
import com.grao.waterschool.human.entiry.dto.UserLogin;
import com.grao.waterschool.human.entiry.po.TSysTuser;
import com.grao.waterschool.human.entiry.vo.OAuthResponseVO;
import com.grao.waterschool.human.entiry.vo.ResetPassword;
import com.grao.waterschool.human.entiry.vo.ResourcesVO;
import com.grao.waterschool.human.manager.service.ICCAuthorizeService;
import com.grao.waterschool.human.manager.service.LoginService;
import com.grao.waterschool.human.mapper.TSysTuserMapper;

import com.grao.waterschool.human.mapper.TWschoolUserRoleLinkMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.*;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import static com.grao.waterschool.human.manager.service.impl.UserServiceImpl.generateRandomId;

@Slf4j
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    TSysTuserMapper tuserMapper;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private static RestTemplate restTemplate = new RestTemplate();

    @Autowired
    TWschoolUserRoleLinkMapper tuserRoleLinkMapper;

    @Autowired
    ICCAuthorizeService iccService;

    private final String url = "http://10.0.25.226/admin/API/accounts/authorize";

    private final String AUTHORIZEURL = "https://sso.sdwcvc.cn/oauth2/authorize";

    private final String ACCESSTOKENURL = "https://sso.sdwcvc.cn/oauth2/access_token";

    private final String RESOURCES = "https://sso.sdwcvc.cn/oauth2/resources";

    private final String CLIENTID = "s6qmt9m4y0n7gu4k58gw934wl6vytsr6";

    private final String SECRET = "DP6mu#CbEawl?Ob4-L5[FMPIk";


    @Override
    public SaResult login(UserLogin userLogin) throws Exception {
        TSysTuser s = tuserMapper.selectUserByName(userLogin.getUsername());
        Assert.notNull(s, "用户不存在");


        if (bCryptPasswordEncoder.matches(userLogin.getPwd(), s.getTpassword())) {

            StpUtil.login(s.getId());
            StpUtil.getSession().set("user", s);

//            登录成功后直接调用ICC认证进入系统
//            iccService.loginForICC();

            return SaResult.data(StpUtil.getTokenInfo());
        }
        return SaResult.error("用户名或密码错误");
    }

    public SaResult loginForOAuth2(LoginInfo info) throws Exception {
        Map<String,Object> result = new HashMap<>();
        Map<String, String> loginInfo = new HashMap<>();
        loginInfo.put("client_id", CLIENTID);
        loginInfo.put("client_secret", SECRET);
        loginInfo.put("code", info.getCode());

        log.info("clientId:{}, clientSecret:{}, Code:{}", loginInfo.get("client_id"), loginInfo.get("client_secret"), loginInfo.get("code"));
        ObjectMapper mapper = new ObjectMapper();

        StringBuilder encodedParams = new StringBuilder();
        for (Map.Entry<String, String> entry : loginInfo.entrySet()) {
            if (encodedParams.length() > 0) {
                encodedParams.append("&");
            }
            encodedParams.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8));
            encodedParams.append("=");
            encodedParams.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
        }
        log.info("编码参数: {}", encodedParams);

        HttpHeaders headers = getHttpHeadersByurlencoded();
        HttpEntity<String> requestEntity = new HttpEntity<>(encodedParams.toString(), headers);
        ResponseEntity<String> responseEntity = restTemplate.exchange(ACCESSTOKENURL, HttpMethod.POST, requestEntity, String.class);

        String responseBody = responseEntity.getBody();
        log.info("响应: {}", responseBody);
        OAuthResponseVO oAuthResponse = mapper.readValue(responseBody, OAuthResponseVO.class);

        // 获取uid和token
        String uid = oAuthResponse.getData().getUid();
        String token = oAuthResponse.getData().getToken();
        log.info("uid:{}, token:{}", uid, token);
        Map<String, String> resources = new HashMap<>();
        resources.put("client_id", CLIENTID);
        resources.put("token", token);

        // 对资源请求参数进行URL编码
        StringBuilder encodedResources = new StringBuilder();
        for (Map.Entry<String, String> entry : resources.entrySet()) {
            if (encodedResources.length() > 0) {
                encodedResources.append("&");
            }
            encodedResources.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8));
            encodedResources.append("=");
            encodedResources.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
        }
        log.info("编码资源参数: {}", encodedResources);

        HttpHeaders headersResources = getHttpHeadersByurlencoded();
        HttpEntity<String> requestEntityResources = new HttpEntity<>(encodedResources.toString(), headersResources);
        ResponseEntity<String> responseEntityResources = restTemplate.exchange(RESOURCES, HttpMethod.POST, requestEntityResources, String.class);
        String respons = responseEntityResources.getBody();

        ResourcesVO resourcesVO = mapper.readValue(respons, ResourcesVO.class);

        // 获取用户参数
        String userName = resourcesVO.getData().getXm();
        String yhbh = resourcesVO.getData().getYhbh();
        String role = resourcesVO.getData().getRolenum();
        String phone = resourcesVO.getData().getSj();

        String roleStr = "";
        if("1".equals(role)){
            roleStr = "教师";
        } else if("2".equals(role)){
            roleStr = "学生";
        } else if("3".equals(role)){
            roleStr = "其他";
        }
        result.put("role",roleStr);
        // 这里获取用户yhbh去库里查，查不到就创建一个，查得到就直接登录。然后其他地方不用改
        TSysTuser tSysTuser = tuserMapper.selectUserByTeacherNum(yhbh);
        if (tSysTuser == null) {
            tSysTuser = new TSysTuser();
            tSysTuser.setId(generateRandomId());
            tSysTuser.setTusername(userName);
            tSysTuser.setTeacherNum(yhbh);
            tSysTuser.setTphone(phone);

            tuserMapper.insert(tSysTuser);
            tuserRoleLinkMapper.insert(tSysTuser.getTeacherNum(), 1);

            StpUtil.login(tSysTuser.getId());
            StpUtil.getSession().set("user", tSysTuser);
            // 登录成功后直接调用ICC认证进入系统
            iccService.loginForICC();
        } else {
            StpUtil.login(tSysTuser.getId());
            StpUtil.getSession().set("user", tSysTuser);
            // 登录成功后直接调用ICC认证进入系统
            iccService.loginForICC();
        }

        result.put("tokenInfo",StpUtil.getTokenInfo());
        return SaResult.data(result);
    }

    @Override
    public SaResult getUserInfo() {
        String userName = tuserMapper.selectUserById(StpUtil.getLoginIdAsInt());
        Assert.notNull(userName, "用户不存在");
        return SaResult.data(userName);
    }

    @Override
    public SaResult logout() {
        if (!StpUtil.isLogin()) {
            return SaResult.error("未登录");
        }
        String loginId = StpUtil.getLoginIdAsString();
        StpUtil.logout();
        return SaResult.data("用户: " + loginId + " 退出成功");

    }

    @Override
    public SaResult resetPassword(ResetPassword resetPassword) {
        TSysTuser tSysTuser = tuserMapper.selectUserByTeacherNum(resetPassword.getTeacherNum());
        if (tSysTuser == null) {
            return SaResult.error("用户不存在");
        }
        String encode = BCrypt.hashpw(resetPassword.getNewPassword());
        resetPassword.setNewPassword(encode);
        tuserMapper.updateNewasswordByTeacherNum(resetPassword);
        return SaResult.ok("修改成功");
    }

    @Override
    public SaResult disableUserByTeacherId(String teacherNum) {
        TSysTuser tSysTuser = tuserMapper.selectUserByTeacherNum(teacherNum);
        if (tSysTuser == null) {
            return SaResult.error("用户不存在");
        }
        if (tSysTuser.getDeleteStatus() == null) {
            tuserMapper.disableUserByTeacherId(teacherNum);
            return SaResult.ok("禁用成功");
        } else {
            tuserMapper.enableUserByTeacherId(teacherNum);
            return SaResult.ok("启用成功");
        }

    }

    private static HttpHeaders getHttpHeaders() {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        return headers;
    }


    private HttpHeaders getHttpHeadersByurlencoded() {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "application/x-www-form-urlencoded");
        return headers;
    }
}
